home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / WASTE 1.2 / WASTE Demo ƒ / WEDemoEvents.c < prev    next >
Text File  |  1996-06-20  |  10KB  |  496 lines

  1. /*
  2.     WASTE Demo Project:
  3.     Events Handling
  4.  
  5.     Copyright © 1993-1996 Marco Piovanelli
  6.     All Rights Reserved
  7.  
  8.     C port by John C. Daub
  9. */
  10.  
  11. #ifndef __APPLEEVENTS__
  12. #include <AppleEvents.h>
  13. #endif
  14.  
  15. #ifndef __AEREGISTRY__
  16. #include <AERegistry.h>
  17. #endif
  18.  
  19. #ifndef __DISKINIT__
  20. #include <DiskInit.h>
  21. #endif
  22.  
  23. #ifndef __TEXTSERVICES__
  24. #include <TextServices.h>
  25. #endif
  26.  
  27. #ifndef __WEDEMOAPP__
  28. #include "WEDemoIntf.h"
  29. #endif
  30.  
  31. static UInt32        sSleepTime = 0;            // sleep time for WaitNextEvent()
  32. static RgnHandle    sMouseRgn = nil;        // mouse region for WaitNextEvent()
  33.  
  34.  
  35. void AdjustCursor( Point mouseLoc, RgnHandle mouseRgn )
  36. {
  37.     WindowRef window;
  38.  
  39.     // by default, set mouseRgn to the whole QuickDraw coordinate plane,
  40.     // so that we never get mouse moved events
  41.  
  42.     SetRectRgn( mouseRgn, -SHRT_MAX, -SHRT_MAX, SHRT_MAX, SHRT_MAX );
  43.  
  44.     // give text services a chance to set the cursor shape
  45.  
  46.     if ( gHasTextServices )
  47.     {
  48.         if ( SetTSMCursor( mouseLoc ) )
  49.             return;
  50.     }
  51.  
  52.     // if there is a window open, give WEAdjustCursor an opportunity to set the cursor
  53.     // WEAdjustCursor intersects mouseRgn (if supplied) with a region within which
  54.     // the cursor is to retain its shape
  55.     // (if the cursor is outside the view region, this is subtracted from mouseRgn )
  56.  
  57.     if ( ( window = FrontWindow( ) ) != nil )
  58.     {
  59.         if ( WEAdjustCursor( mouseLoc, mouseRgn, GetWindowWE( window ) ) )
  60.             return;
  61.     }
  62.  
  63.     // set the cursor to the arrow cursor
  64.  
  65.     SetCursor( &qd.arrow );
  66. }
  67.  
  68. void DoMouseDown( const EventRecord *event )
  69. {
  70.     WindowRef window;
  71.     short partCode;
  72.  
  73.     // find out where this click when down in
  74.  
  75.     partCode = FindWindow( event->where, &window );
  76.  
  77.     // dispatch on partCode
  78.  
  79.     switch ( partCode )
  80.     {
  81.         case inMenuBar:
  82.             PrepareMenus( );
  83.             DoMenuChoice( MenuSelect( event->where ), event->modifiers );
  84.             break;
  85.  
  86.         case inSysWindow:
  87. #if defined ( UNIVERSAL_INTERFACES_VERSION ) && ( UNIVERSAL_INTERFACES_VERSION >= 0x211 )
  88.             SystemClick( event, window );
  89. #else
  90.             //    Universal Headers prior to version 2.1.2 define SystemClick
  91.             //    incorrectly if STRICT_WINDOWS == 1
  92.             SystemClick( event, (WindowPtr) window );
  93. #endif
  94.             break;
  95.  
  96.         case inContent:
  97.             if ( DoContent( event->where, event, window ) )
  98.             {
  99.                 SelectWindow( window );
  100.             }
  101.             break;
  102.  
  103.         case inDrag:
  104.             DoDrag( event->where, window );
  105.             break;
  106.  
  107.         case inGrow:
  108.             DoGrow( event->where, window );
  109.             break;
  110.  
  111.         case inGoAway:
  112.             if ( TrackGoAway( window, event->where ) )
  113.             {
  114.                 if ( DoClose( closingWindow, savingAsk, window ) != noErr )
  115.                 {
  116.                     // insert error handling
  117.                 }
  118.             }
  119.             break;
  120.  
  121.         case inZoomIn:
  122.         case inZoomOut:
  123.             if ( TrackBox( window, event->where, partCode ) )
  124.             {
  125.                 DoZoom( partCode, window );
  126.             }
  127.             break;
  128.     }    // switch
  129. }
  130.  
  131. void DoKeyDown( const EventRecord *event )
  132. {
  133.     short key;
  134.     Boolean isCmdKey;
  135.  
  136.     // extract character code from event message
  137.  
  138.     key = ( event->message & charCodeMask );
  139.  
  140.     // is this a command+key combo?
  141.  
  142.     isCmdKey = ( ( event->modifiers & cmdKey ) != 0 );
  143.  
  144.     // map function keys to the equivalent command+key combos
  145.     // note that all fuction keys generate the same code, i.e. 0x10
  146.  
  147.     if ( key == 0x10 )
  148.     {
  149.         isCmdKey = true;
  150.  
  151.         switch( ( event->message & keyCodeMask ) >> 8 )
  152.         {
  153.             case keyF1:
  154.                 key = 'z';
  155.                 break;
  156.  
  157.             case keyF2:
  158.                 key = 'x';
  159.                 break;
  160.  
  161.             case keyF3:
  162.                 key = 'c';
  163.                 break;
  164.  
  165.             case keyF4:
  166.                 key = 'v';
  167.                 break;
  168.  
  169.             default:
  170.                 key = 0;
  171.  
  172.         }    // switch
  173.     }    // if
  174.  
  175.     // command + printable character combos are routed to MenuKey( )
  176.     // but be sure to pass command + arrow key combos to WEKey( )
  177.  
  178.     if ( isCmdKey && (key >= 0x20 ) )
  179.     {
  180.         PrepareMenus( );
  181.         DoMenuChoice( MenuKey( key ), event->modifiers );
  182.     }
  183.     else
  184.     {
  185.         DoKey( key, event );
  186.     }
  187. }
  188.  
  189. void DoDiskEvent( const EventRecord *event )
  190. {
  191.     Point dialogCorner;
  192.  
  193.     if ( ( event->message >> 16) != noErr )
  194.     {
  195.         SetPt( &dialogCorner, 112, 80 );
  196.         DIBadMount( dialogCorner, event->message );
  197.     }
  198. }
  199.  
  200. void DoOSEvent( const EventRecord *event )
  201. {
  202.     short        osMessage;
  203.     WindowRef    window;
  204.  
  205.     // extract the OS message field from the event record
  206.  
  207.     osMessage = ( event->message & osEvtMessageMask) >> 24 ;
  208.  
  209.     // dispatch on osMessage
  210.  
  211.     switch( osMessage )
  212.     {
  213.         case suspendResumeMessage:
  214.             if ( ( window = FrontWindow( ) ) != nil )
  215.             {
  216.                 DoActivate( (event->message & resumeFlag) != 0, window );
  217.             }
  218.             break;
  219.  
  220.         case mouseMovedMessage:
  221.             // nothing
  222.             break;
  223.     }
  224. }
  225.  
  226. void DoHighLevelEvent( const EventRecord *event )
  227. {
  228.     AEProcessAppleEvent( event );
  229. }
  230.  
  231. void DoNullEvent( const EventRecord *event )
  232. {
  233. #pragma unused (event)
  234.  
  235.     WindowRef window;
  236.  
  237.     if ( ( window = FrontWindow( ) ) != nil )
  238.     {
  239.         WEIdle( &sSleepTime, GetWindowWE(window) );
  240.     }
  241.     else
  242.     {
  243.         sSleepTime = LONG_MAX;
  244.     }
  245. }
  246.  
  247. void DoWindowEvent( const EventRecord *event )
  248. {
  249.     WindowRef window;
  250.  
  251.     // the message field of the event record contains the window reference
  252.  
  253.     window = (WindowRef) event->message;
  254.  
  255.     // make sure this window is an application window; check the windowKind field
  256.  
  257.     if ( GetWindowKind( window ) != userKind )
  258.         return;
  259.  
  260.     switch ( event->what )
  261.     {
  262.         case updateEvt:
  263.             DoUpdate( window );
  264.             break;
  265.  
  266.         case activateEvt:
  267.             DoActivate( ( event->modifiers & activeFlag) != 0, window );
  268.             break;
  269.     }
  270. }
  271.  
  272. void ProcessEvent( void )
  273. {
  274.     EventRecord event;
  275.     Boolean gotEvent;
  276.  
  277.     gotEvent = WaitNextEvent( everyEvent, &event, sSleepTime, sMouseRgn );
  278.  
  279.     // give text services a chance to intercept this event
  280.     // if TSMEvent( ) handles the event, it will set event.what to nullEvent
  281.  
  282.     if ( gHasTextServices )
  283.     {
  284.         TSMEvent( &event );
  285.     }
  286.  
  287.     // adjust cursor shape and set mouse region
  288.     // (we assume event.where is the current mouse position in global coordinates
  289.     // if event.what <= osEvt; high-level events store the event ID there)
  290.  
  291.     if ( event.what <= osEvt )
  292.     {
  293.         AdjustCursor( event.where, sMouseRgn );
  294.     }
  295.  
  296.     // dispatch on event.what
  297.  
  298.     switch( event.what )
  299.     {
  300.         case nullEvent:
  301.             DoNullEvent( &event );
  302.             break;
  303.  
  304.         case mouseDown:
  305.             DoMouseDown( &event);
  306.             break;
  307.  
  308.         case keyDown:
  309.         case autoKey:
  310.             DoKeyDown( &event );
  311.             break;
  312.  
  313.         case updateEvt:
  314.         case activateEvt:
  315.             DoWindowEvent( &event );
  316.             break;
  317.  
  318.         case diskEvt:
  319.             DoDiskEvent( &event );
  320.             break;
  321.  
  322.         case osEvt:
  323.             DoOSEvent( &event );
  324.             break;
  325.  
  326.         case kHighLevelEvent:
  327.             DoHighLevelEvent( &event );
  328.             break;
  329.     }    // switch
  330.  
  331.     if ( gotEvent )
  332.     {
  333.         sSleepTime = 0;  // force early idle after non-idle event
  334.     }
  335. }
  336.  
  337. OSErr GotRequiredParams( const AppleEvent *ae )
  338. {
  339.     DescType actualType;
  340.     Size actualSize;
  341.     OSErr err;
  342.  
  343.     err = AEGetAttributePtr( ae, keyMissedKeywordAttr, typeWildCard, &actualType, nil, 0, &actualSize );
  344.  
  345.     return    ( err == errAEDescNotFound ) ? noErr :
  346.             ( err == noErr ) ? errAEParamMissed : err;
  347. }
  348.  
  349. static pascal OSErr    HandleOpenDocument( const AppleEvent *ae, AppleEvent *reply, long refCon )
  350. {
  351. #pragma unused ( reply, refCon )
  352.     AEDescList        docList;
  353.     AEKeyword        keyword;
  354.     DescType        actualType;
  355.     Size            actualSize;
  356.     long            numberOfDocuments, i;
  357.     FSSpec            fileSpec;
  358.     OSErr            err;
  359.  
  360.     docList.descriptorType = typeNull;
  361.     docList.dataHandle = nil;
  362.  
  363.     // extract direct parameter from the Apple event
  364.  
  365.     if ( ( err = AEGetParamDesc( ae, keyDirectObject, typeAEList, &docList ) ) != noErr )
  366.         goto cleanup;
  367.  
  368.     // perform the recommended check for additional required parameters
  369.  
  370.     if ( ( err = GotRequiredParams( ae ) ) != noErr )
  371.         goto cleanup;
  372.  
  373.     // count the items in the list of aliases
  374.  
  375.     if ( ( err = AECountItems( &docList, &numberOfDocuments ) ) != noErr )
  376.         goto cleanup;
  377.  
  378.     for ( i = 1; i <= numberOfDocuments; i++ )
  379.     {
  380.         // coerce the nth alias to a file system specification record
  381.  
  382.         if ( ( err = AEGetNthPtr( &docList, i, typeFSS, &keyword, &actualType,
  383.                 &fileSpec, sizeof( fileSpec ), &actualSize ) ) != noErr )
  384.             goto cleanup;
  385.  
  386.         // open the specified file
  387.  
  388.         if ( ( err = CreateWindow( &fileSpec ) ) != noErr )
  389.             goto cleanup;
  390.     }
  391.  
  392. cleanup:
  393.     AEDisposeDesc( &docList );
  394.     return err;
  395. }
  396.  
  397. static pascal OSErr    HandleOpenApplication( const AppleEvent *ae, AppleEvent *reply, long refCon )
  398. {
  399. #pragma unused ( reply, refCon )
  400.     OSErr        err;
  401.  
  402.     // perform the recommended check for additional required parameters
  403.  
  404.     if ( ( err = GotRequiredParams( ae ) ) != noErr )
  405.         goto cleanup;
  406.  
  407.     // create a new window from scratch
  408.  
  409.     err = CreateWindow( nil );
  410.  
  411. cleanup:
  412.     return err;
  413. }
  414.  
  415. static pascal OSErr    HandleQuitApplication( const AppleEvent *ae, AppleEvent *reply, long refCon )
  416. {
  417. #pragma unused (reply, refCon)
  418.  
  419.     AEKeyword        optKey;
  420.     DescType        actualType;
  421.     Size            actualSize;
  422.     SavingOption    saving;
  423.     OSErr            err;
  424.  
  425.     // default saving option is savingAsk;
  426.  
  427.     saving = savingAsk;
  428.  
  429.     // extract optional save options
  430.  
  431.     if ( ( err = AEGetParamPtr( ae, keyAESaveOptions, typeEnumerated, &actualType, &optKey, sizeof( optKey ), &actualSize ) ) == noErr )
  432.     {
  433.         if ( optKey == kAEYes )
  434.         {
  435.             saving = savingYes;
  436.         }
  437.         else if (optKey == kAENo )
  438.         {
  439.             saving = savingNo;
  440.         }
  441.         else if ( optKey != kAEAsk )
  442.         {
  443.             err = paramErr;    // for want of a better code
  444.             goto cleanup;
  445.         }
  446.     }
  447.  
  448.     // perform the recommended check for additional required parameters
  449.  
  450.     if ( ( err = GotRequiredParams( ae ) ) != noErr )
  451.         goto cleanup;
  452.  
  453.     // actually do the quit stuff
  454.  
  455.     err = DoQuit( saving );
  456.  
  457. cleanup:
  458.     return err;
  459. }
  460.  
  461. OSErr InitializeEvents( void )
  462. {
  463.     OSErr    err;
  464.  
  465.     // allocate space for the mouse region
  466.  
  467.     sMouseRgn = NewRgn( );
  468.  
  469.     // install AppleEvent handlers for the Required Suite
  470.  
  471.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc( HandleOpenApplication ), 0, false ) ) != noErr )
  472.         goto cleanup;
  473.  
  474.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc( HandleOpenDocument ), kDoOpen, false ) ) != noErr )
  475.         goto cleanup;
  476.  
  477.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc( HandleOpenDocument ), kDoPrint, false ) ) != noErr )
  478.         goto cleanup;
  479.  
  480.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc( HandleQuitApplication ), 0, false ) ) != noErr )
  481.         goto cleanup;
  482.  
  483.     // install Apple event handlers for a subset of the Core suite
  484.  
  485.     if ( ( err = InstallCoreHandlers( ) ) != noErr )
  486.         goto cleanup;
  487.  
  488.     // install Apple event handlers for inline input
  489.  
  490.     if ( ( err = WEInstallTSMHandlers( ) ) != noErr )
  491.         goto cleanup;
  492.  
  493. cleanup:
  494.     return err;
  495. }
  496.